<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
    <meta http-equiv="content-language" content="zh-CN" />
    

    
    <meta name="viewport" content="width=device-width, initial-scale=0.5">
    

    
    <title>data.table -- 1基本函数</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.8/clipboard.min.js"></script>
    
    
    
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">

    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">

    <link rel="stylesheet" href="/css/stylesheet.css">
    <link rel="stylesheet" href="/css/home.css">

    
    
        <style type="text/css">
        body { background-color: #fbf6ec;}
        </style>
    
    
                
        
        
            <link rel="stylesheet" href="/css/main.css"/>
        




        
        
        
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.min.css"  />
         
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.min.js"></script>
        
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/r.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/yaml.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/latex.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/matlab.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/mathematica.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/julia.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/julia-repl.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/powershell.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/bash.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/shell.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/python.min.js"></script>
        
        <script>hljs.initHighlightingOnLoad();</script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
     
     
</head>


<body>
    <script>
        window.addEventListener("resize", resizeThrottler, false);

        var resizeTimeout;
        function resizeThrottler() {
        
        if ( !resizeTimeout ) {
            resizeTimeout = setTimeout(function() {
            resizeTimeout = null;
            actualResizeHandler();
        
            
            }, 66);
        }
        }
        actualResizeHandler()
        function actualResizeHandler() {
                if (/mobile/i.test(navigator.userAgent) || /android/i.test(navigator.userAgent))
                {
                    document.body.classList.add('mobile');
                }else{
                    document.body.classList.remove('mobile');  
                }
    }</script>

    
      
      
            <nav class="navbar navbar-default navbar-static-top" style="opacity: .9" role="navigation">
        <div class="container-fluid">
            
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">

                    <span class="sr-only">Toggle navigation</span>
                    <span class="big-icon icon-bar"></span>
                    <span class="big-icon icon-bar"></span>
                    <span class="big-icon icon-bar"></span>

                </button>
                <a class="navbar-brand" href="/">zsc</a>
            </div>

            <div class="navbar-collapse collapse" id="bs-example-navbar-collapse-1" style="height: auto;">
                <ul class="nav navbar-nav navbar-right" style="font-size: 100%">
                    
                        
                            
                            <li class=""><a href="/about/">About</a></li>
                            
                            <li class=""><a href="/categories/">Categories</a></li>
                            
                            <li class=""><a href="/">Home</a></li>
                            
                            <li class=""><a href="/tags/">Tags</a></li>
                            
                            <li class=""><a href="/issue/">存在的问题</a></li>
                            
                        
                    
                </ul>
            </div>
        </div>
    </nav>










<div class="inner">
    



    <div class="blog-post">
        
                <div>
            <h2 align="center" id = "singe-h2">
                data.table -- 1基本函数
                <time>
                    <br>
                    <span> 
                        <i class="fa fa-user-edit" style="color:#888;font-size: 80%;"></i>
                        zsc 
                    </span>
                    &nbsp 
                    <span>                 
                        <i class="fa fa-calendar-alt" style="color:#888;font-size: 80%;"></i>
                        2018-01-16 
                    </span>
                </time>
                
                
                <div>
                    <ul class="tags">
                        
                        <span>标签:</span>
                        <li><a class="link" href="/tags/r"> #r </a></li><li><a class="link" href="/tags/data.table"> #data.table </a></li>
                        
                        <span> </span>
                        
                    </ul>
                    
                </div>
            </h2>
        </div>
    
        
        <section id="content">
            <p>data.table本质上是一个list，它们的列包含的元素个数都相同。</p>
<h1 id="1数据的读写">1、数据的读写</h1>
<h3 id="11数据读入fread">1.1数据读入－－fread</h3>
<p>选其常用的参数如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#a6e22e">fread</span>(input,na.strings<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;NA&#34;</span>, file, stringsAsFactors<span style="color:#f92672">=</span><span style="color:#66d9ef">FALSE</span>,encoding<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;unknown&#34;</span>, <span style="color:#66d9ef">...</span>)
</span></span></code></pre></div><ul>
<li>input 入的文件对象，<code>fread</code>函数可以自动判断分隔符类型，自动判断首行是否是列标题，同时默认读入时字符型变量不会变为因子型。也可也从网页读取数据</li>
<li>na.strings,对NA的解释；</li>
<li>file文件路径，再确保没有执行shell命令时很有用，也可以在input参数输入;</li>
<li>stringsASFactors是否转化字符串为因子，</li>
<li>encoding，默认&quot;unknown&quot;，其它可能&quot;UTF-8&quot;或者&quot;Latin-1&quot;，不是用来重新编码的，而是允许处理的字符串在本机编码;</li>
<li>showProgress = T   显示进度条</li>
<li>integer64 当数据列中有大于2 ^ 31的整数,可能会丢失精度</li>
<li>quote  对带双引号的字符添加转义,在R中正常显示,但是输出时,可能会引起成倍的双引号,因此建议使用<code>fwrite</code>时,设置该参数<code>quote = FALSE</code></li>
</ul>
<h3 id="12数据写入fwrite">1.2数据写入－－fwrite</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#a6e22e">fwrite</span>(x, file <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#34;</span>, append <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>, na <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#34;</span>, row.names <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>, col.names <span style="color:#f92672">=</span> <span style="color:#66d9ef">TRUE</span>,logicalAsInt <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>, <span style="color:#66d9ef">...</span>)
</span></span></code></pre></div><ul>
<li>x,比如data.frame和data.table等R的对象；</li>
<li>file，输出文件名,&ldquo;&ldquo;意味着直接输出到操作台；</li>
<li>append，如果TRUE,在原文件的后面添加；默认删除原来文件的数据，重新存储。</li>
<li>na,na值的表示，默认&rdquo;&quot;；</li>
<li>row.names，是否写出行名，因为data.table没有行名，所以默认FALSE；</li>
<li>col.names ，是否写出列名，默认TRUE，如果没有定义，并且append=TRUE和文件存在，那么就会默认使用FALSE;</li>
<li>logicalAsInt,逻辑值作为数字写出还是作为FALSE和TRUE写出；</li>
</ul>
<h2 id="13--数据框转为datatable">1.3  数据框转为data.table</h2>
<p>对于数据的处理，<code>data.table</code>包提供了一个非常简洁的通用格式：<code>DT[i,j,by]</code>，</p>
<ul>
<li>其中<code>i</code>控制列, <code>j</code>控制列, <code>by</code>控制分组. 上述表达式的意思是: 对于数据集<code>DT</code>，先选取子集行<code>i</code>,  然后通过<code>by</code>分组计算<code>j</code>。<code>i</code>设定数据的选取条件，<code>j</code>设定结果的计算方式，<code>by</code>设定数据的分组情况。通过这个，我们可以在一行代码中很方便地完成处理过程。首先需要把数据变为data.table类型</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">library(data.table)
library(magrittr)
### 方法一: 赋值转换
mtcars_dt &lt;- data.table(mtcars) # 也可以强制转化 as.data.table()

### 方法二: 引用转换
setDT(mtcars)  # 不需要赋值,这是引用转换, mtcars这个数据集已经变成了data.table 数据类型了
</code></pre><h1 id="2-数据行列筛选-----i-参数">2. 数据行列筛选 &mdash; i 参数</h1>
<p><strong>行筛选：&ndash;i参数</strong></p>
<ul>
<li>直接采用逻辑语句（慢）</li>
<li>使用主键(会对筛选的数据进行重排序&ndash;适中)</li>
<li>二级索引（不重排序，按原数据的顺序排序&ndash;快）</li>
</ul>
<h2 id="21-直接采用逻辑语句慢">2.1 直接采用逻辑语句（慢）</h2>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">mtcars_dt &lt;- data.table(mtcars) # 一共32行,11列
#直接采用逻辑语句（慢）
mtcars_dt[cyl==8 ]
mtcars_dt[cyl==8 &amp; carb==4]
mtcars_dt[cyl %in% c(&#34;8&#34;,&#34;6&#34;)]# 等价 mtcars_dt[cyl %in% c(8,6)]
</code></pre><h2 id="22-设置获取使用主键适中">2.2 设置/获取/使用主键(适中)</h2>
<table>
<thead>
<tr>
<th>函数</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>setkey(x,V1)</code></td>
<td>该函数可以对一个data.table按照某一列进行排序,排序之后,这个data.table 对象会被标记为排过序了, 由于不会在内存中复制被排序的data.table对象,所以非常高效.</td>
</tr>
<tr>
<td><code>setkey(x,V1,V2,V3, ...)</code></td>
<td>等价于<code>setkeyv(x,c(&quot;V1&quot;,&quot;V2&quot;,...) )</code></td>
</tr>
<tr>
<td><code>setkeyv(x,c(&quot;V1&quot;,&quot;V2&quot;,...) )</code></td>
<td>可以按照多列一起排序.先根据V1排序,然后根据V2排序, 以此类推.</td>
</tr>
<tr>
<td><code>table()</code></td>
<td>查看内存中所有data.table 的详细信息,包括key键,</td>
</tr>
</tbody>
</table>
<ul>
<li>
<p><strong><code>setkey(x,V1)</code>传入列名作为参数，不需要引号, 而<code>setkeyv(x,c(&quot;V1&quot;,&quot;V2&quot;,...) )</code> 传入一个字符型的向量, 这两个函数都没有返回值, 直接对data.table进行更新操作,和<code>:=</code>类似</strong></p>
</li>
<li>
<p><strong>每一个table.table中只有一组key键, 像普通的data.frame, 每一行有且只有一个行名且行名具有唯一性, 行名可以看做是data.frame的索引. 而data.table可以利用主键进行索引, 且可以对多列设置主键,且主键不强调唯一性. 也就是说，不同列的主键可以是一样的。既然行可以通过主键排序，那么排序的时候，具有同样主键的一些行，会被排在一起。</strong></p>
</li>
<li>
<p><strong>在data.table里，操作符&rdquo;:=&ldquo;和所有的以set开头函数（比如setkey,setorder,setname等）一样，它们都会更新输入的原数据。</strong></p>
</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">#使用主键(会对筛选的数据进行重排序--适中)
mtcars_dt &lt;- data.table(mtcars) 
setkey(mtcars_dt,cyl,carb)# 设置key键
mtcars_dt #可以看出已经排序了
tables()              # 查看内存中所有data.table 的详细信息,包括key键
iris_dt = data.table(iris)
tables()              # 
setkeyv(mtcars_dt,c(&#34;cyl&#34;,&#34;carb&#34;))#先设置的cyl,carb列为主键
mtcars_dt[.(8,4)]     # 等价 mtcars_dt[cyl==8 &amp; carb==4]
tables()              # 查看内存中所有data.table 的详细信息
</code></pre><h2 id="23-二级索引indices快">2.3 二级索引<code>(indices)</code>（快）</h2>
<h4 id="a--什么是二级索引-二级索引和主键有什么区别">a)  <strong>什么是二级索引? 二级索引和主键有什么区别?</strong></h4>
<ul>
<li>前面介绍了<code>setkey</code> 和<code>setkeyv</code>的使用,每一次使用<code>setkey</code>, data.table 对象都会在内存里被重新排序, 时间复杂度是<code>O(nlogn)</code>. 而  <code>setindex</code> 和<code>setindexv</code> 则不会对data.table对象进行重新排序, 它只会计算某列的顺序，将这个顺序向量保存在一个额外的，叫做index的属性里面。 此外,一个data.table对象只能有一组key,  但是可以有多个二级索引(indices). 二级索引的时间复杂度是<code>O(logn)</code></li>
</ul>
<table>
<thead>
<tr>
<th>函数</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>setindex(x,V1)</code></td>
<td>设置索引&mdash;即将V1列设置为该data.table的二级索引 <br> 等价<code>setindexv(x,c(&quot;V1&quot;))</code></td>
</tr>
<tr>
<td><code>setindex(x,V1,V2,...)</code></td>
<td>设置多列索引&mdash;即将V1,V2列设置为该data.table的二级索引<br/> 等价<code>setindexv(x,c(&quot;V1&quot;,&quot;V2&quot;,...))</code></td>
</tr>
<tr>
<td><code>setindexv(x,c(&quot;V1&quot;,&quot;V2&quot;,...))</code></td>
<td>以字符的方式设置索引</td>
</tr>
<tr>
<td><code>setindex(x, NULL)</code></td>
<td>删除所有的二级索引。</td>
</tr>
<tr>
<td><code>indices(x) </code></td>
<td>获取data.table对象的所有二级索引, 如果该data.table没有二级索引，那么返回NULL。</td>
</tr>
</tbody>
</table>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}"># 设置和获取二级索引
mtcars_dt &lt;- data.table(mtcars) 
setindex(mtcars_dt,cyl,carb) # 等价于 setindexv(mtcars_dt,c(&#34;cyl&#34;,&#34;carb&#34;))
names(attributes(mtcars_dt)) # 查询data.table 的属性
indices(mtcars_dt)
mtcars_dt #  注意并没有对数据进行重新排序, 而setkey会对数据进行重新排序
setindexv(mtcars_dt,c(&#34;vs&#34;, &#34;am&#34;, &#34;gear&#34;,&#34;carb&#34;))
indices(mtcars_dt)
</code></pre><h4 id="b为什么使用二级索引">b)为什么使用二级索引</h4>
<p>原因是对一个data.table重新排序成本太高, 除非你要进行大量选子集的操作,建议使用setkey 来提取子集.
我们想快速地提取子集(subset)同时又不必重新排序,此时二级索引就派上用处了.</p>
<h2 id="24-二级索引的快速使用-----参数on">2.4 二级索引的快速使用 &mdash; 参数on</h2>
<p>上面我们都在讲先设置二级索引,然后在进行操作,这样能不能合成一步?&mdash;-于是参数<code>on</code>诞生了, 参数<code>on</code>使得语法更简洁，并且能自动创建并重用二级索引</p>
<p><strong>参数on</strong></p>
<ul>
<li>通过创建索引进行subset。每次都能节省setindex()的时间。</li>
<li>通过检查属性，可以简单地重用已经存在的二级索引。</li>
<li>参数on必须是一个字符型的向量。</li>
<li>注意参数on也可以用来指定主键。事实上，为了更佳的可读性，我们鼓励在参数on里面指定主键。</li>
<li>参数<code>on</code>它不会把这个二级索引自动创建为data.table的一个属性。需要额外设置参数才可以(设<code>verbose = TRUE</code>).</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">mtcars_dt[.(1),on=&#34;am&#34;]#同时满足cyl=8,gear=4的行
## 等价的备选方案 -- mtcars_dt[list(1), on = &#34;am&#34;]
## 注意 on=&#34;am&#34;表明我们要基于am这一列进行过滤,过滤的条件是am == 1, 1必须放置.()里面
## 原因是 am是numeric类型,如果不是numeric类型,就不用这样做

iris_dt = data.table(iris)
iris_dt[&#34;setosa&#34;,on=&#34;Species&#34;]  
#等价的备选方案
iris_dt[.(&#34;setosa&#34;),on=&#34;Species&#34;] 
iris_dt[list(&#34;setosa&#34;),on=&#34;Species&#34;] 

# 选择 Species =setosa 或者 Species =virginica
iris_dt[.(c(&#34;setosa&#34;,&#34;virginica&#34;)) ,on=&#34;Species&#34;] 
iris_dt[.(c(&#34;setosa&#34;,&#34;virginica&#34;),c(3.0)) ,on=c(&#34;Species&#34;,&#34;Sepal.Width&#34;)] 

# 注意小心有NA行,原因在于Petal.Length列没有等于5.1的值
iris_dt[.(c(&#34;setosa&#34;,&#34;virginica&#34;),c(5.1)) ,on=c(&#34;Species&#34;,&#34;Petal.Length&#34;)] 


#### on参数也可以像j那样直接使用列名 ,无需加引号
mtcars_dt[.(8,4),on=c(&#34;cyl&#34;,&#34;carb&#34;)]#同时满足cyl=8,gear=4的行
mtcars_dt[.(8,4),on=.(cyl,carb)]# 等价同上,
</code></pre><h2 id="25-自动索引-----只支持操作符--和-in">2.5 自动索引 &mdash; 只支持操作符 == 和 %in%</h2>
<p>回顾一下，我们先学习如何通过主键使用快速二分法搜索进行subset。接着，我们学习了使用二级索引，它带来更好的效果，而且语法也更简洁。</p>
<p>等等，有没有更好的方法？</p>
<p>有！优化R的原生语法，使用内置的索引。这样我们毋需使用新的语法，就能得到同样的效果。这就是自动索引。
目前，<strong>它只支持操作符 == 和 %in% 。而且只对一列起作用</strong>。某一列会被自动创建为索引，并且作为data.table的属性保存起来。这跟参数on不同，参数on会每次创建一个临时索引，所以才会被叫做“二级索引”。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span>iris_dt[Petal.Length <span style="color:#f92672">==</span> <span style="color:#ae81ff">5.1</span>, ] 
</span></span><span style="display:flex;"><span>iris_dt[Petal.Length <span style="color:#f92672">%in%</span> <span style="color:#a6e22e">c</span>(<span style="color:#ae81ff">5.1</span>,<span style="color:#ae81ff">5.2</span>), ] 
</span></span></code></pre></div><p><strong>注意, 以上都是针对<code>i</code>参数设置,因此可以同<code>j</code>参数, <code>by</code>参数同时使用</strong></p>
<p><strong>还有, 在进行行筛选时,尽量打个逗号,区分<code>i</code>和<code>j</code></strong></p>
<h1 id="3--列筛选---j参数">3  列筛选：&ndash; j参数</h1>
<h2 id="31-格式--等价list">3.1 <code>.()</code>格式 == 等价list()</h2>
<p><strong>用<code>.()</code>来包围列名，和<code>list()</code> 等价</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#75715e"># 列筛选 --方法一, 直接输入列名</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, .(mpg, cyl, hp)] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>()
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>)]<span style="color:#75715e"># 返回的都是data.table</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>), with <span style="color:#f92672">=</span>F]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 列筛选 --方法二 如果没用list()或者.()包围列名 ，则返回的是向量（这不是我们想要的结果），如下</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#a6e22e">c</span>(mpg, cyl, hp)] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 列筛选 --方法三, 可以把列名改写成对应的数字列,但返回的是data.table类型</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#a6e22e">c</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">4</span>)] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>()
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#a6e22e">c</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">4</span>)] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">class</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 列筛选-- 方法四, 如果列名已经存储到一个变量里面了, 怎么根据它来选择列</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">library</span>(data.table)
</span></span><span style="display:flex;"><span>mtcars_dt <span style="color:#f92672">=</span> <span style="color:#a6e22e">as.data.table</span>(mtcars)
</span></span><span style="display:flex;"><span>a <span style="color:#f92672">=</span> <span style="color:#a6e22e">c</span>(<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">2</span>,<span style="color:#ae81ff">4</span>)
</span></span><span style="display:flex;"><span>b <span style="color:#f92672">=</span> <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>)
</span></span><span style="display:flex;"><span>mtcars_dt[,..a] <span style="color:#75715e"># 在变量名前加两个点,  如果这样输入: mtcars_dt[,a], 则报错</span>
</span></span><span style="display:flex;"><span>mtcars_dt[,..b]<span style="color:#75715e"># 在变量名前加两个点,  如果这样输入: mtcars_dt[,b], 则报错</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 列筛选 --方法五, 要排除列名怎么办，可以用数字</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#f92672">-</span><span style="color:#a6e22e">c</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">4</span>)] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>() <span style="color:#75715e"># 等价</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>) <span style="color:#f92672">:=</span><span style="color:#66d9ef">NULL</span>]  <span style="color:#75715e"># 等价</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#f92672">-</span><span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>), with <span style="color:#f92672">=</span> F] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>() <span style="color:#75715e"># 等价</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#f92672">!</span><span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>), with <span style="color:#f92672">=</span> F] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>() <span style="color:#75715e"># 等价</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 下面只能用冒号(:)链接，不然会报错</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#f92672">-</span>(<span style="color:#ae81ff">2</span><span style="color:#f92672">:</span><span style="color:#ae81ff">4</span>)] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>() <span style="color:#75715e"># 删除第2:4列变量</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, mpg<span style="color:#f92672">:</span>disp, with <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>() <span style="color:#75715e"># 等价</span>
</span></span><span style="display:flex;"><span>mtcars_dt[,<span style="color:#f92672">-</span>(mpg<span style="color:#f92672">:</span>disp), with <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>() <span style="color:#75715e"># 等价</span>
</span></span></code></pre></div><h2 id="32-在j参数上可以进行计算">3.2 在j参数上可以进行计算：</h2>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}"># 返回按列计算的值
mtcars_dt[,.(sum(mpg),mean(cyl))]

# 当列的长度不一的时候，会循环对齐
mtcars_dt[,.(mpg,mean(cyl))] %&gt;% head()


# 还可以输入多个表达式，用花括号括起来即可
mtcars_dt[,{print(mpg);plot(disp)}]

# {} 还有帮助我们隐藏一些过度中间变量
mtcars_dt[,.(x = cyl^2 +1, y = cyl^2 +2)] %&gt;% head() # 这样cyl^2计算了两次,这样效率慢

mtcars_dt[,{temp = cyl^2; .(x = temp+1,y=temp+2)}] %&gt;% head() 
</code></pre><p><strong>关键词<code>.SD</code> 和<code>.SDcol</code> 的作用</strong> , 后面会讲解</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 对data.table的每一列进行计算</span>
</span></span><span style="display:flex;"><span>mtcars_dt[,<span style="color:#a6e22e">sapply</span>(.SD, <span style="color:#a6e22e">function</span>(x){<span style="color:#a6e22e">sum</span>(<span style="color:#a6e22e">is.na</span>(x))<span style="color:#f92672">/</span>.N})]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 也可以指定列进行计算</span>
</span></span><span style="display:flex;"><span>mtcars_dt[,<span style="color:#a6e22e">sapply</span>(.SD, <span style="color:#a6e22e">function</span>(x){<span style="color:#a6e22e">sum</span>(<span style="color:#a6e22e">is.na</span>(x))<span style="color:#f92672">/</span>.N}),.SDcol <span style="color:#f92672">=</span> <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;A&#34;</span>,<span style="color:#e6db74">&#34;B&#34;</span>,<span style="color:#e6db74">&#34;C&#34;</span>)]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>iris_dt <span style="color:#f92672">=</span> <span style="color:#a6e22e">data.table</span>(iris)
</span></span><span style="display:flex;"><span>col_names <span style="color:#f92672">=</span> <span style="color:#a6e22e">colnames</span>(iris_dt)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 计算所有数值变量的均值, 可以先对变量名进行筛选</span>
</span></span><span style="display:flex;"><span>num_col <span style="color:#f92672">=</span> <span style="color:#a6e22e">sapply</span>(iris_dt, <span style="color:#a6e22e">function</span>(x) <span style="color:#a6e22e">class</span>(x) <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;numeric&#34;</span> )
</span></span><span style="display:flex;"><span>iris_dt[, <span style="color:#a6e22e">lapply</span>(.SD, mean), .SDcols <span style="color:#f92672">=</span> num_col]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#####  在数据框中把指定的列转换为因子列</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 方法一   ---- 这种方法已被弃用 with=F, 推荐使用方法2 </span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># col_names 为一个字符向量</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># iris_dt[, col_names := lapply(.SD, function(x)as.factor(x)),.SDcols = col_names,with=F]</span>
</span></span><span style="display:flex;"><span>iris_dt[,col_names,with<span style="color:#f92672">=</span>F]  <span style="color:#75715e"># 选择以col_names变量的内容的列</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 方法二</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## (col_names):=  代表的是字符串向量，如果只使用col_names则表示列名为col_names的变量</span>
</span></span><span style="display:flex;"><span>iris_dt[, (col_names) <span style="color:#f92672">:=</span> <span style="color:#a6e22e">lapply</span>(.SD, <span style="color:#a6e22e">function</span>(x)<span style="color:#a6e22e">as.factor</span>(x)) , .SDcols <span style="color:#f92672">=</span> col_names]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>iris_dt[,(<span style="color:#e6db74">&#34;Sepal.Length&#34;</span>)<span style="color:#f92672">:=</span><span style="color:#a6e22e">as.factor</span>(Sepal.Length)] <span style="color:#75715e">#同上</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>                                
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 如果左边用数字并打上() 代表第几列，指定第几列的操作</span>
</span></span><span style="display:flex;"><span>iris_dt[,(<span style="color:#ae81ff">2</span><span style="color:#f92672">:</span><span style="color:#ae81ff">3</span>)<span style="color:#f92672">:=</span>Species] <span style="color:#75715e"># 把第2：3列的值进行更新，即第2:3列都为Species列</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">### 用函数对列名进行筛选后,然后对这些列进行统一处理</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#eg: 列名以S结尾的列全部转为因子,    </span>
</span></span><span style="display:flex;"><span>iris_dt[, <span style="color:#a6e22e">lapply</span>(.SD, <span style="color:#a6e22e">function</span>(x)<span style="color:#a6e22e">as.factor</span>(x)) , .SDcols <span style="color:#f92672">=</span> <span style="color:#a6e22e">endsWith</span>(<span style="color:#a6e22e">names</span>(iris_dt), <span style="color:#e6db74">&#34;S&#34;</span>)]
</span></span><span style="display:flex;"><span><span style="color:#75715e"># startsWith(names(iris_dt), &#34;S&#34;) # 表示以S开头的筛选变量方式</span>
</span></span><span style="display:flex;"><span>                 
</span></span><span style="display:flex;"><span>                 
</span></span></code></pre></div><h2 id="33-选取子集">3.3 选取子集</h2>
<p>选取子集仍然采用<code>subeset</code>函数，语法格式为：<code>subset(x, subset, select)</code>，x是data.table对象，subset是行满足条件，select是列满足条件</p>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}"># 用 .() 来包围列名，和list() 等价，都返回data.table数据类型,只要参数 j 返回一个list，这个list的每一个元素都会被转换成结果data.table的一列

subset(mtcars_dt,cyl==8,select =c(&#39;mpg&#39;,&#39;cyl&#39;,&#39;disp&#39;))
# 等价
mtcars_dt[cyl==8,.(mpg,cyl,disp)]
# 等价
mtcars_dt[cyl==8,list(mpg,cyl,disp)]

## 注意 ，没用list()或者.()包围列名 ，则返回的是向量，如下
mtcars_dt[,c(mpg,cyl,hp)] 
</code></pre><h2 id="34--对列进行排序">3.4  对列进行排序</h2>
<ul>
<li>排序采用<code>setorder</code>函数，输入待排序的列名，默认升序，降序列名前加<code>-</code></li>
<li>注意：升序，降序都是按assic 值的大学排序</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#a6e22e">setorder</span>(mtcars_dt,mpg,<span style="color:#f92672">-</span>hp) <span style="color:#75715e">#注意，这里直接对原数据进行了重排序，这点和R很多函数不一样，</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#几乎等价</span>
</span></span><span style="display:flex;"><span>mtcars_dt<span style="color:#a6e22e">[order</span>(cyl,<span style="color:#f92672">-</span>hp)] <span style="color:#75715e">#这个就基本符合R语言规律，不改变原数据。</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 还可以使用key键排序,这样会改变原数据</span>
</span></span></code></pre></div><h2 id="35-对列进行增删变量">3.5 对列进行增删变量</h2>
<p><strong>都是直接对原数据进行修改，无需重复赋值</strong></p>
<h3 id="351-添加变量有三种语法格式">3.5.1 添加变量有三种语法格式：</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span>DT[i, LHS<span style="color:#f92672">:=</span>RHS, by<span style="color:#f92672">=</span><span style="color:#66d9ef">...</span>] <span style="color:#75715e">#适用单变量添加，等号（＝）前面为新的变量名,没有写明变量名，自动为V+  </span>
</span></span><span style="display:flex;"><span>DT[i, <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;LHS1&#34;</span>,<span style="color:#e6db74">&#34;LHS2&#34;</span>) <span style="color:#f92672">:=</span> <span style="color:#a6e22e">list</span>(RHS1, RHS2), by<span style="color:#f92672">=</span><span style="color:#66d9ef">...</span>] <span style="color:#75715e">#双变量添加  </span>
</span></span><span style="display:flex;"><span>DT[i, <span style="color:#a6e22e">`:=`</span>(LHS1<span style="color:#f92672">=</span>RHS1,LHS2<span style="color:#f92672">=</span>RHS2, <span style="color:#66d9ef">...</span>), by<span style="color:#f92672">=</span><span style="color:#66d9ef">...</span>] <span style="color:#75715e">#多变量添加，注意`:=`  </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 有条件的添加变量</span>
</span></span><span style="display:flex;"><span>mtcars_dt <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">data.table</span>(mtcars) 
</span></span><span style="display:flex;"><span>mtcars_dt[, cyl1<span style="color:#f92672">:=</span> <span style="color:#ae81ff">1</span><span style="color:#f92672">*</span>(cyl <span style="color:#f92672">&lt;=</span> <span style="color:#ae81ff">6</span>)]
</span></span><span style="display:flex;"><span>mtcars_dt[, cyl2<span style="color:#f92672">:=</span> <span style="color:#a6e22e">ifelse</span>(cyl <span style="color:#f92672">&lt;=</span><span style="color:#ae81ff">6</span>, <span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">0</span>)]
</span></span><span style="display:flex;"><span>mtcars_dt[, cyl_mpg<span style="color:#f92672">:=</span> <span style="color:#a6e22e">ifelse</span>(cyl <span style="color:#f92672">&lt;=</span><span style="color:#ae81ff">6</span>, mpg,cyl)]<span style="color:#75715e"># 当cyl小于6时,则用mpg的数据,大于6时,则用cyl值保持不变</span>
</span></span></code></pre></div><h3 id="352-删除变量-----变量null">3.5.2 删除变量 &mdash; <code>变量:=NULL</code></h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 这里发现一个bug，数据集被改动了,但是rstudio中的变量的维度没变，但是数据集确实改变了</span>
</span></span><span style="display:flex;"><span>mtcars_dt[,<span style="color:#a6e22e">`:=`</span>(mpg1<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span><span style="color:#f92672">/</span>mpg,new<span style="color:#f92672">=</span>cyl<span style="color:#f92672">+</span>gear)]<span style="color:#75715e">#增加变量mpg1 与new变量</span>
</span></span><span style="display:flex;"><span>mtcars_dt[,mpg1<span style="color:#f92672">:=</span><span style="color:#66d9ef">NULL</span>] <span style="color:#75715e">#删除变量mpg1  也可以mtcars_dt[,`:=`(mpg1=NULL,new=NULL)],也可以用 mtcars_dt[, c(&#34;mpg&#34;) :=NULL] </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 如果要删除多列时，可用以下方法,</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>) <span style="color:#f92672">:=</span><span style="color:#66d9ef">NULL</span>]  <span style="color:#75715e"># 注意用 :=  会直接更改原数据</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#f92672">-</span><span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>), with <span style="color:#f92672">=</span> F]  <span style="color:#75715e"># 这个会产生一个副本（或者叫拷贝）</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#f92672">!</span><span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>), with <span style="color:#f92672">=</span> F] <span style="color:#75715e"># 同上，产生拷贝</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#f92672">-</span><span style="color:#a6e22e">c</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">4</span>)]     <span style="color:#75715e">#  同上，产生拷贝</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 删除多列</span>
</span></span><span style="display:flex;"><span>col <span style="color:#f92672">=</span> <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;mpg&#34;</span>, <span style="color:#e6db74">&#34;cyl&#34;</span>, <span style="color:#e6db74">&#34;hp&#34;</span>)
</span></span><span style="display:flex;"><span>mtcars_dt[, col <span style="color:#f92672">:=</span><span style="color:#66d9ef">NULL</span>]  <span style="color:#75715e"># 这个只能删除列名为col的变量</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>mtcars_dt[, (col) <span style="color:#f92672">:=</span><span style="color:#66d9ef">NULL</span>] <span style="color:#75715e"># 能删除以col为变量的内容作为mtcars的列名，</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 上面等价mtcars_dt[, c(&#34;mpg&#34;, &#34;cyl&#34;, &#34;hp&#34;) :=NULL] </span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 下面只能有冒号(:)链接，不然会报错</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, mpg<span style="color:#f92672">:</span>disp, with <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>() <span style="color:#75715e"># 等价</span>
</span></span><span style="display:flex;"><span>mtcars_dt[,<span style="color:#f92672">-</span>(mpg<span style="color:#f92672">:</span>disp), with <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>() <span style="color:#75715e"># 等价</span>
</span></span></code></pre></div><p><strong>理解数据存储以及变量名</strong> 。比如：数字，字符串 ，矩阵的内容，都会直接存在内存中，把数字3赋值给变量a,就相当于a指向数字3，改变a不会对内存进行修改，只是指针发生了改变，</p>
<p><strong>操作符“:=”会更新原数据</strong>。操作符“:=”对输入的数据进行浅度复制，只是一份指向列的指针向量的复制，在内存里，数据不是真的被复制了。他会随着指针指向的对象变化而变化，</p>
<p>**不更新原数据用函数 copy()。**函数 copy() 对输入参数进行深度复制，因此对副本做的所有更新操作，都不会对原数据生效。简单理解：就是在内存中创建了一个和原来一模一样的数据.</p>
<h1 id="4-分组汇总by参数">4. 分组汇总－－by参数</h1>
<h2 id="41-分组汇总只需在by指定分组变量在j指定计算函数即可">4.1 分组汇总只需在<code>by</code>指定分组变量，在<code>j</code>指定计算函数即可</h2>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">#按cyl与vs分组，对统计分组下的mpg均值，disp的总和,分组数据个数num，共返回cyl，vs，以及分组下的三个新变量 
mtcars_dt[,.(mean_mpg = mean(mpg),num=length(mpg),sum_disp = sum(disp)),by=.(cyl,vs)] 
</code></pre><h2 id="42-datatable有一个特殊的变量n可以直接计算分组的观测值个数">4.2 data.table有一个**特殊的变量<code>.N</code>**可以直接计算分组的观测值个数。</h2>
<pre><code>- 当参数j里面只有一列，我们可以省略 .()，如下：mtcars_dt[,.N,by=.(cyl,vs)]	 
- 当参数by里面只有一列，我们可以省略 .()，如下：mtcars_dt[,.N,by=cyl]
</code></pre>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">mtcars_dt[,.(mean_mpg = mean(mpg),.N),by=.(cyl,vs)]
</code></pre><h2 id="43-by参数还有接受表达式">4.3 by参数还有接受表达式：</h2>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}"># 可以对要分组的列进行表达式判断，按其真假进行分组
mtcars_dt[,.(mean_mpg = mean(mpg),.N),by=.(cyl&gt;5,vs)]
# 也可以用函数进行简单的分组
mtcars_dt[,.(hp),by=sign(cyl-6)]
</code></pre><h2 id="44-sd-和sdcol-关键词">4.4 <code>.SD</code> 和<code>.SDcol</code> 关键词</h2>
<p><strong>对j参数进行计算时，必须分别对每列指定 mean() 函数吗 ？</strong></p>
<p>如上面的例子，要对分组变量进行计算难道都要指定每一列？可以采用<code>.SD</code> 函数，它常和<code>.SDcols</code>函数联合使用。</p>
<ul>
<li><code>.SD</code> 是经过<code>i</code> 和<code>by</code> 处理之后剩下的那部分数据集, 本质是一个<code>data.table</code>对象.</li>
<li>另一种理解, <strong><code>.SD</code>代表行经过<code>i</code> 筛选后, 除了<code>by</code>参数指定的列以外的所有列组成的新的data.table, 是原数据的子集</strong></li>
<li>首先,对<code>i</code>参数进行筛选, 然后把 <code>by</code>参数指定的那一列会被提前到首列, 其余列被按<code>by</code>指定的列进行分组组成新的<code>data.table</code>对象, 分成多少组,就有多少个<code>data.table</code> 对象, 这里的多个<code>data.table</code>对象出现的顺序是按照<code>by</code>指定列值出现的顺序</li>
<li><code>.SD</code>只能在位置j中使用, 且只能在<code>:=</code>右边使用</li>
<li>由于<code>.SD</code> 默认包含用于分组的所有列。我们需要指定列进行计算 &mdash;&ndash;可用关键词<code>.SDcol</code></li>
<li><code>.SDcols</code>指定<code>.SD </code>包括哪些列. eg: <code>.SDcols = c(&quot;disp&quot;,&quot;hp&quot;)</code>,  则  <code>.SD</code> 从默认的所有列改为只包含<code>disp</code>和<code>hp</code>这两列。</li>
<li>我们也可以使用<code> -</code> 或者<code>!</code>来移除列。比如:我们指定<code> !(colA:colB)</code> 或者<code> -(colA:colB)</code>表示移除从 <code>colA</code> 到 <code>colB</code> 的所有列。</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">library(data.table)
mtcars_dt = data.table::as.data.table(mtcars)
mtcars_dt[, .SD, by=cyl] # 注意此时cyl 从第二列变成了第一列,故by指定的列提前到第一列,其余列顺序保持不变

mtcars_dt[, print(.SD), by=cyl] # 注意了多个data.table对象, 每一个对象是按照cyl值的先后顺序输出的

mtcars_dt[, lapply(.SD[, 1:2, with=F], mean), by=cyl] #.SD代表除了by指定的所有列组成的新data.table, 并选择新的data.table的前两列进行计算

# 按cyl vs变量进行分组后，对其余的每一列求均值
mtcars_dt[,lapply(.SD, mean),by=.(cyl,vs)]

# 按cyl分组以后对其余变量求和
mtcars_dt[,lapply(.SD, sum),by=.(cyl)] 

# 如果要对大量的变量做聚合计算，可以使用.SD函数，和.SDcols函数。
# 默认的，.SD函数指对所有变量进行计算
mtcars_dt[, lapply(.SD, mean)]

#只对某些特定的列 结合.SDcols参数
mtcars_dt[, lapply(.SD, mean), .SDcols = c(&#34;cyl&#34;, &#34;vs&#34;)]#只对cyl, vs列进行计算

# 对多个变量实现多个统计指标计算
mtcars_dt[, sapply(.SD, function(x) c(mean=mean(x), median=median(x)))]
</code></pre><h2 id="45-如果要对子集进行分组统计怎么办即对选出的i进行分组统计">4.5 如果要对子集进行分组统计怎么办？，即对选出的i进行分组统计.</h2>
<p>可用<code>by=列名即可</code>允许按每一个已知i的子集分组，在使用by=.EACHI时需要设置键值</p>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">mtcars_dt[cyl==4 | cyl==8,mean(mpg),by = cyl]
</code></pre><h1 id="5分组汇总的同时排序--keyby">5分组汇总的同时排序 —— keyby</h1>
<p>和上面的by参数有什么不同？</p>
<p>data.table本身就被设计成能保持原数据的顺序。<strong>在一些情况下，必须保持原来的顺序</strong>。但是，有时我们<strong>希望自动根据分组的变量排序</strong>。使用<code>keyby</code>参数，使用参数<code>keyby</code>自动将引用的列设置为主键</p>
<ol>
<li>如何按照分组的变量排序</li>
</ol>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">mtcars_dt &lt;- data.table(mtcars)
# 未设置主键时，分组变量cyl，vs是按原来mtcars_dt数据集中的顺序排序的
mtcars_dt[, .(mean_mpg = mean(mpg),.N), by=.(cyl,vs)]

#设置主键 ，把cyl,vs列设置主键--会根据分组的变量排序。
mtcars_dt[, .(mean_mpg = mean(mpg),.N), keyby=.(cyl,vs)]# 注意这里keyby里面不能进行降序排列，若在vs前面加一个负号，这等于在变量vs乘－1

# 等价
mtcars_dt[,.(mean_mpg = mean(mpg),.N),by=.(cyl,vs)][order(cyl,vs)]
</code></pre><h1 id="6-chaining表达式">6. chaining表达式</h1>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span>我们可以一个接一个地添加表达式，做一系列操作，就像这样：
</span></span><span style="display:flex;"><span>   <span style="color:#ae81ff">1</span>，DT[...][...][...]。
</span></span><span style="display:flex;"><span>   <span style="color:#ae81ff">2</span>，DT[...
</span></span><span style="display:flex;"><span>	         ][...
</span></span><span style="display:flex;"><span> 	         ][...
</span></span><span style="display:flex;"><span> 		        ]
</span></span></code></pre></div><p>比如要提取前面几行就可以<code>DT[...][1:5]</code>,</p>
<ul>
<li>大多数情况下没有问题, 有些时候可以在最后面加个空, eg: <code>DT[...][1:5][]</code> , 这样可以保证返回<code>data.table</code> 数据格式</li>
<li>发生这种原因,大多数和 <code>:=</code> 有关系, 如下</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#75715e"># eg:</span>
</span></span><span style="display:flex;"><span>a <span style="color:#f92672">=</span> iris_dt[1<span style="color:#f92672">:</span><span style="color:#ae81ff">3</span>, <span style="color:#ae81ff">1</span><span style="color:#f92672">:</span><span style="color:#ae81ff">4</span>][, id <span style="color:#f92672">:=</span> <span style="color:#ae81ff">1</span><span style="color:#f92672">:</span><span style="color:#ae81ff">3</span>]  <span style="color:#75715e"># 不会在控制台显示结果, 必须要显示打印: print(a)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">### 如果换一个写法就不会啦</span>
</span></span><span style="display:flex;"><span>a <span style="color:#f92672">=</span> iris_dt[1<span style="color:#f92672">:</span><span style="color:#ae81ff">3</span>, <span style="color:#ae81ff">1</span><span style="color:#f92672">:</span><span style="color:#ae81ff">4</span>][, id <span style="color:#f92672">:=</span> <span style="color:#ae81ff">1</span><span style="color:#f92672">:</span><span style="color:#ae81ff">3</span>][]  <span style="color:#75715e"># 直接正常显示,打印</span>
</span></span></code></pre></div><p><strong>以上就是data.table的基本操作,后续更新一些本报的一些基本概念和其他函数</strong></p>
<h1 id="7总结">7总结</h1>
<p>data.table的语法形式是：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span>DT[i, j, by]
</span></span></code></pre></div><p>指定参数i：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#f92672">*</span> 类似于data.frame，我们可以subset行，除非不需要重复地使用 DT<span style="color:#f92672">$</span>，既然我们能将列当做变量来引用。 
</span></span><span style="display:flex;"><span><span style="color:#f92672">*</span> 我们可以使用<span style="color:#a6e22e">order</span>()排序。为了得到更快速的效果，<span style="color:#a6e22e">order</span>()函数内部使用了data.table的快速排序。 
</span></span><span style="display:flex;"><span>我们可以通过参数i做更多的事，得到更快速的选取和连结。
</span></span></code></pre></div><p>指定参数j：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#f92672">*</span> 以data.table的形式选取列：DT[, .(colA, colB)]。
</span></span><span style="display:flex;"><span><span style="color:#f92672">*</span> 以data.frame的形式选取列：DT[, <span style="color:#a6e22e">c</span>(<span style="color:#e6db74">&#34;colA&#34;</span>, <span style="color:#e6db74">&#34;colB&#34;</span>), with<span style="color:#f92672">=</span><span style="color:#66d9ef">FALSE</span>]。
</span></span><span style="display:flex;"><span><span style="color:#f92672">*</span> 按列进行计算：DT[, <span style="color:#a6e22e">.(sum</span>(colA), <span style="color:#a6e22e">mean</span>(colB))]。
</span></span><span style="display:flex;"><span><span style="color:#f92672">*</span> 如果需要：DT[, .(sA <span style="color:#f92672">=</span><span style="color:#a6e22e">sum</span>(colA), mB <span style="color:#f92672">=</span> <span style="color:#a6e22e">mean</span>(colB))]。
</span></span><span style="display:flex;"><span><span style="color:#f92672">*</span> 和i共同使用：DT[colA <span style="color:#f92672">&gt;</span> value, <span style="color:#a6e22e">sum</span>(colB)]。
</span></span></code></pre></div><p>指定参数by：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#f92672">*</span> 通过by，我们可以指定列或表达式，进行分组。参数j可以很灵活地配置参数i和by实现强大的功能。
</span></span><span style="display:flex;"><span><span style="color:#f92672">*</span> by可以指定多个列，也可以指定表达式。
</span></span><span style="display:flex;"><span><span style="color:#f92672">*</span> 我们可以用 keyby，对分组的结果自动排序。
</span></span><span style="display:flex;"><span><span style="color:#f92672">*</span> 我们可以在参数j中指定 .SD 和 .SDcols，对复数的列进行操作。例如：   
</span></span><span style="display:flex;"><span>  <span style="color:#ae81ff">1</span>.把函数fun 应用到所有 .SDcols指定的列上，同时对参数by指定的列进行分组：
</span></span><span style="display:flex;"><span>  							DT[, <span style="color:#a6e22e">lapply</span>(.SD, fun), by<span style="color:#f92672">=</span>., .SDcols<span style="color:#f92672">=</span><span style="color:#66d9ef">...</span>]。 
</span></span><span style="display:flex;"><span>  <span style="color:#ae81ff">2</span>.返回每组册前两行：DT[, <span style="color:#a6e22e">head</span>(.SD, <span style="color:#ae81ff">2</span>), by<span style="color:#f92672">=</span>.]。
</span></span><span style="display:flex;"><span>  <span style="color:#ae81ff">3</span>.三个参数联合使用：DT[col <span style="color:#f92672">&gt;</span> val, <span style="color:#a6e22e">head</span>(.SD, <span style="color:#ae81ff">1</span>), by<span style="color:#f92672">=</span>.]。
</span></span></code></pre></div><p>小提示：
只要j返回一个list，这个list的每个元素都会是结果data.table的一列。</p>
<p><a href="https://youngspring1.github.io/2016/2016-03-13-datatable1/">https://youngspring1.github.io/2016/2016-03-13-datatable1/</a></p>
<p><a href="https://youngspring1.github.io/2016/2016-03-21-datatable2/">https://youngspring1.github.io/2016/2016-03-21-datatable2/</a></p>
<p><a href="https://youngspring1.github.io/2016/2016-03-22-datatable3/">https://youngspring1.github.io/2016/2016-03-22-datatable3/</a></p>
<p><a href="https://youngspring1.github.io/2016/2016-04-02-datatable4/">https://youngspring1.github.io/2016/2016-04-02-datatable4/</a></p>
<p><a href="https://youngspring1.github.io/2016/2016-04-08-datatable5/">https://youngspring1.github.io/2016/2016-04-08-datatable5/</a></p>

        </section>
    </div>
    <br>
    
    




<span id="/md/2018-01-16-datatable1/" class="leancloud_visitors" data-flag-title="data.table -- 1基本函数">
  <span class="post-meta-item-text">文章总阅读量 </span>
  <span class="leancloud-visitors-count"><i class="leancloud-visitors-count"></i></span>次;
  <p></p>
</span>



    

    
    
    <button id="edit-button" class="icon-button" type="button" title="Fork and edit" aria-label="Fork and edit" aria-haspopup="true" aria-expanded="false" aria-controls="edit">
        <i class="fa fa-edit">编辑本文</i>
    </button>
    
    
    

    <br>
    <hr>
    <li style="float:left;list-style:none">
        
        <a class="previous" href="/md/2018-01-07-%E4%BD%BF%E7%94%A8r%E8%BD%AF%E4%BB%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/"> 上一篇: R软件常见问题</a>
        
    </li>
    <li style="float:right;list-style:none">
        
        <a class="next" href="/md/2018-01-17-datatable2/"> 下一篇: data.table -- 2基本概念</a>
        
    </li>
     
    
    <script src="/js/copyCode.js"></script>
    <script src="/js/tooltips.js"></script>
    
   
    <script>
    [].slice.call(document.querySelectorAll('table')).forEach(function(el) {
        var wrapper = document.createElement('div');
        wrapper.className = 'table-area';
        el.parentNode.insertBefore(wrapper, el);
        el.parentNode.removeChild(el);
        wrapper.appendChild(el);
        $("table").wrap("<div class='table-area'></div>");
    })
    </script>

    
<br>
<hr>


<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-111691389-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag() { dataLayer.push(arguments); }
  gtag('js', new Date());

  gtag('config', 'UA-111691389-1');
</script>




      
      
      

       
      
      
      <script>
              document.getElementById("edit-button").addEventListener("click", function () {
                  var editWindow = window.open("https:\/\/github.com\/zoushucai\/blogmmm/edit/master/content/md\/2018-01-16-datatable1.md");
              });</script>
      
          




<script>
  function resizeIframe(obj) {
    obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
  } 
</script>



    </style>
    <script type="text/javascript">
    function showdiv(){
        document.getElementById("divtocTableOfContents").style.display="block";
        document.getElementById("strHref").innerHTML="目录收起-";
        document.getElementById('divTableOfContents').style.width="22%";
        document.getElementById('divTableOfContents').style.height="55%";
        document.getElementById('divTableOfContents').style.top="25%";
        document.getElementById('divTableOfContents').style.bottom="5%";
        document.getElementById("strHref").href="javascript:hidediv()";
    }
    function hidediv(){
        document.getElementById("divtocTableOfContents").style.display="none";
        document.getElementById("strHref").innerHTML="目录展开+";
        document.getElementById("strHref").href="javascript:showdiv()";
        document.getElementById('divTableOfContents').style.width="10%";
        document.getElementById('divTableOfContents').style.height="5%";
    }
    </script>
</body>

</html>
</div> 







    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/mathtex-script-type.min.js" integrity="sha384-LJ2FmexL77rmGm6SIpxq7y+XA6bkLzGZEgCywzKOZG/ws4va9fUVu2neMjvc3zdv" crossorigin="anonymous"></script>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js"></script>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            renderMathInElement(document.body, {
            delimiters: [
                            {left: "$$", right: "$$", display: true},
                            {left: "$", right: "$", display: false},
                            {left: "\\(", right: "\\)", display: false},
                            {left: "\\[", right: "\\]", display: true}
                        ]
            });
        });
    </script>













<br>
<div class="inner">
              
            
          
          
  
          
  
  <div id="vcomments"></div>
  
  <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
  
  <script src='//unpkg.com/valine/dist/Valine.min.js'></script>
  <script type="text/javascript">
    new Valine({
        el: '#vcomments' ,
        appId: 'HfHPKPkLa0cBEDPcdBAHuqMv-gzGzoHsz',
        appKey: 'r5RJAasN8e0mB9sq6y9pEcX0',
        lang:'zh-CN',
        notify:  false , 
        verify:  false  ,
        avatar:'identicon', 
        placeholder: '说点什么吧...',
        visitor:  true 
    });
  </script>

</div>

<br>
<br>
<footer>
    <p style="float:right;margin-right: 5%;margin-top: 0%;">
        &copy; 2022 <a href="https://github.com/zoushucai">zsc</a>
      </p>
</footer>
<br>
<br>


